using System.Web.Mvc;
using AgileBoard.Core;
using SharpArch.Core.PersistenceSupport;
using SharpArch.Core.DomainModel;
using System.Collections.Generic;
using System;
using SharpArch.Web.NHibernate;
using NHibernate.Validator.Engine;
using System.Text;
using SharpArch.Web.CommonValidator;
using SharpArch.Core;

namespace AgileBoard.Web.Controllers
{
    [HandleError]
    public class StoriesController : Controller
    {
        public StoriesController(IRepository<Story> storyRepository) {
            Check.Require(storyRepository != null, "storyRepository may not be null");

            this.storyRepository = storyRepository;
        }

        [Transaction]
        public ActionResult Index() {
            IList<Story> stories = storyRepository.GetAll();
            return View(stories);
        }

        [Transaction]
        public ActionResult Show(int id) {
            Story story = storyRepository.Get(id);
            return View(story);
        }

        public ActionResult Create(string id) {
            StoryFormViewModel viewModel = StoryFormViewModel.CreateStoryFormViewModel();
            viewModel.State = int.Parse(id);
            return View(viewModel);
        }

        [ValidateAntiForgeryToken]
        [Transaction]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create(Story story) {
            if (ViewData.ModelState.IsValid && story.IsValid()) {

                storyRepository.SaveOrUpdate(story);

                TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] = 
					"The story was successfully created.";
                return RedirectToAction("Index", "Iterations");
            }

            StoryFormViewModel viewModel = StoryFormViewModel.CreateStoryFormViewModel();
            viewModel.Story = story;
            return View(viewModel);
        }

        [Transaction]
        public ActionResult Edit(int id) {
            StoryFormViewModel viewModel = StoryFormViewModel.CreateStoryFormViewModel();
            viewModel.Story = storyRepository.Get(id);
            return View(viewModel);
        }

        [Transaction]
        public JsonResult Move(string story, string targetState)
        {
            return new JsonResult {
                Data = new
                           {
                               IsAllowed = false,
                               ErrorMessage = "You do not have enough privileges"
                           }, 
                JsonRequestBehavior = JsonRequestBehavior.AllowGet
            }; 
        }

        [ValidateAntiForgeryToken]
        [Transaction]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(Story story) {
            Story storyToUpdate = storyRepository.Get(story.Id);
            TransferFormValuesTo(storyToUpdate, story);

            if (ViewData.ModelState.IsValid && story.IsValid()) {
                TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] = 
					"The story was successfully updated.";
                return RedirectToAction("Index", "Iterations");;
            }
            else {
                storyRepository.DbContext.RollbackTransaction();

				StoryFormViewModel viewModel = StoryFormViewModel.CreateStoryFormViewModel();
				viewModel.Story = story;
				return View(viewModel);
            }
        }

        private void TransferFormValuesTo(Story storyToUpdate, Story storyFromForm) {
			storyToUpdate.Name = storyFromForm.Name;
			storyToUpdate.CreateTime = storyFromForm.CreateTime;
			storyToUpdate.Creator = storyFromForm.Creator;
			storyToUpdate.Size = storyFromForm.Size;
			storyToUpdate.Color = storyFromForm.Color;
			storyToUpdate.Observation = storyFromForm.Observation;
        }

        [Transaction]
        [AcceptVerbs(HttpVerbs.Get)]
        public JsonResult Delete(int id) {
            string resultMessage = "The story was successfully deleted.";
            Story storyToDelete = storyRepository.Get(id);

            if (storyToDelete != null) {
                storyRepository.Delete(storyToDelete);

                try {
                    storyRepository.DbContext.CommitChanges();
                }
                catch {
                    resultMessage = "A problem was encountered preventing the story from being deleted. " +
						"Another item likely depends on this story.";
                    storyRepository.DbContext.RollbackTransaction();
                }
            }
            else {
                resultMessage = "The story could not be found for deletion. It may already have been deleted.";
            }

            TempData[ControllerEnums.GlobalViewDataProperty.PageMessage.ToString()] = resultMessage;
            
            return new JsonResult {
                Data = new { Message = resultMessage}, 
                JsonRequestBehavior = JsonRequestBehavior.AllowGet
            };
        }

		/// <summary>
		/// Holds data to be passed to the Story form for creates and edits
		/// </summary>
        public class StoryFormViewModel
        {
            private StoryFormViewModel() { }

		    /// <summary>
		    /// Creation method for creating the view model. Services may be passed to the creation 
		    /// method to instantiate items such as lists for drop down boxes.
		    /// </summary>
		    /// <param name="parse"></param>
		    public static StoryFormViewModel CreateStoryFormViewModel() {
                StoryFormViewModel viewModel = new StoryFormViewModel();

                return viewModel;
            }

            public Story Story { get; internal set; }
            public int State { get; internal set; }
        }

        private readonly IRepository<Story> storyRepository;
    }
}
